package com.example.shortlink.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.example.shortlink.dao.entity.ShortLink;
import com.example.shortlink.dao.mapper.ShortLinkMapper;
import com.example.shortlink.dto.req.RecycleBinRecoverReqDTO;
import com.example.shortlink.dto.req.RecycleBinRemoveReqDTO;
import com.example.shortlink.dto.req.RecycleBinSaveReqDTO;
import com.example.shortlink.dto.req.ShortLinkRecycleBinPageReqDTO;
import com.example.shortlink.dto.resp.ShortLinkPageRespDTO;
import com.example.shortlink.service.RecycleBinService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import groovy.util.logging.Slf4j;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import static com.example.shortlink.common.constant.RedisKeyConstant.GOTO_IS_NULL_SHORT_LINK_KEY;
import static com.example.shortlink.common.constant.RedisKeyConstant.GOTO_SHORT_LINK_KEY;
import static com.example.shortlink.dao.entity.table.ShortLinkTableDef.SHORT_LINK;

@Slf4j
@Service
@RequiredArgsConstructor
public class RecycleBinServiceImpl extends ServiceImpl<ShortLinkMapper, ShortLink> implements RecycleBinService {

    private final StringRedisTemplate stringRedisTemplate;

    /**
     * 保存回收站
     *
     * @param requestParam 请求参数
     */
    @Override
    public void saveRecycleBin(RecycleBinSaveReqDTO requestParam) {
        UpdateChain.of(ShortLink.class)
                .set(SHORT_LINK.ENABLE_STATUS, Boolean.TRUE)
                .where(SHORT_LINK.FULL_SHORT_URL.eq(requestParam.getFullShortUrl())
                        .and(SHORT_LINK.GID.eq(requestParam.getGid()))
                        .and(SHORT_LINK.ENABLE_STATUS.eq(Boolean.FALSE))
                        .and(SHORT_LINK.DEL_FLAG.eq(Boolean.FALSE)))
                .update();
        stringRedisTemplate.delete(String.format(GOTO_SHORT_LINK_KEY, requestParam.getFullShortUrl()));
    }

    /**
     * 分页查询短链接
     *
     * @param requestParam 分页查询短链接请求参数
     * @return 短链接分页返回结果
     */
    @Override
    public Page<ShortLinkPageRespDTO> pageShortLink(ShortLinkRecycleBinPageReqDTO requestParam) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(SHORT_LINK.DEFAULT_COLUMNS)
                .from(SHORT_LINK)
                .where(SHORT_LINK.GID.in(requestParam.getGidList())
                        .and(SHORT_LINK.ENABLE_STATUS.eq(Boolean.TRUE))
                        .and(SHORT_LINK.DEL_FLAG.eq(Boolean.FALSE)))
                .orderBy(SHORT_LINK.UPDATE_TIME.desc());
        Page<ShortLink> resultPage = mapper.paginate(requestParam, queryWrapper);
        return resultPage.map(each -> {
            ShortLinkPageRespDTO result = BeanUtil.toBean(each, ShortLinkPageRespDTO.class);
            result.setDomain("http://" + result.getDomain());
            return result;
        });
    }

    /**
     * 从回收站恢复短链接
     *
     * @param requestParam 恢复短链接请求参数
     */
    @Override
    public void recoverRecycleBin(RecycleBinRecoverReqDTO requestParam) {
        UpdateChain.of(ShortLink.class)
                .set(SHORT_LINK.ENABLE_STATUS, Boolean.FALSE)
                .where(SHORT_LINK.FULL_SHORT_URL.eq(requestParam.getFullShortUrl())
                        .and(SHORT_LINK.GID.eq(requestParam.getGid()))
                        .and(SHORT_LINK.ENABLE_STATUS.eq(Boolean.TRUE))
                        .and(SHORT_LINK.DEL_FLAG.eq(Boolean.FALSE)))
                .update();
        stringRedisTemplate.delete(String.format(GOTO_IS_NULL_SHORT_LINK_KEY, requestParam.getFullShortUrl()));
    }

    /**
     * 从回收站移除短链接
     *
     * @param requestParam 移除短链接请求参数
     */
    @Override
    public void removeRecycleBin(RecycleBinRemoveReqDTO requestParam) {
        UpdateChain.of(ShortLink.class)
                .set(SHORT_LINK.DEL_TIME, System.currentTimeMillis())
                .set(SHORT_LINK.DEL_FLAG, Boolean.TRUE)
                .where(SHORT_LINK.FULL_SHORT_URL.eq(requestParam.getFullShortUrl())
                        .and(SHORT_LINK.GID.eq(requestParam.getGid()))
                        .and(SHORT_LINK.ENABLE_STATUS.eq(Boolean.TRUE))
                        .and(SHORT_LINK.DEL_TIME.eq(0L))
                        .and(SHORT_LINK.DEL_FLAG.eq(Boolean.FALSE)))
                .update();
    }
}
